1 module hunt.cache.memcached; 2 3 import hunt.cache.cache; 4 import hunt.cache.store; 5 import hunt.cache.nullable; 6 7 version(SUPPORT_MEMCACHED): 8 9 import memcache.memcache; 10 11 class MemcachedCache 12 { 13 14 Nullable!V get(V)(string key) 15 { 16 synchronized(this){ 17 return get_inter!V(key); 18 } 19 } 20 21 Nullable!V[string] getall(V)(string[] keys) 22 { 23 //Memcache's bug not implement mget. 24 //so it's not atomic operation, and transfer .keys.length. times througth network 25 synchronized(this){ 26 Nullable!V[string] mapv; 27 if(keys.length == 0) 28 return mapv; 29 30 foreach(k ; keys){ 31 mapv[k] = get_inter!V(k); 32 } 33 34 return mapv; 35 } 36 37 } 38 bool containsKey(string key) 39 { 40 //Memcache's bug not implement exist , use get inside of. 41 synchronized(this){ 42 return _cache.get!string(key).length > 0; 43 } 44 } 45 46 47 void put(V)(string key , V v , uint expired) 48 { 49 synchronized(this){ 50 put_inter!V(key , v , expired); 51 } 52 } 53 54 55 bool putifAbsent(V)(string key , const V v) 56 { 57 synchronized(this){ 58 59 if(containsKey(key)) 60 return false; 61 62 put_inter!V(key , v , 0); 63 return true; 64 //return _cache.replace(key , cast(string)SerializeToByte!V(v)); 65 } 66 } 67 68 // because memcached api no mset api , so is cost much time to put many. 69 void putAll(V)( V[string] maps , uint expired) 70 { 71 synchronized(this){ 72 73 foreach(k , v ; maps) 74 { 75 put_inter!V(k , v , expired); 76 } 77 } 78 79 } 80 81 bool remove(string key){ 82 synchronized(this){ 83 return remove_inter(key); 84 } 85 } 86 87 // because memcached api no mdel api , so is cost much time to remove many. 88 void removeAll(string[] keys) 89 { 90 synchronized(this){ 91 foreach(k ; keys){ 92 remove_inter(k); 93 } 94 } 95 96 } 97 void clear(){ 98 synchronized(this){ 99 _cache.flush(); 100 } 101 } 102 103 104 105 this(string args ) 106 { 107 if(args == null) 108 args = "--SERVER=127.0.0.1:11211"; 109 _cache = new Memcache(args); 110 } 111 112 113 protected: 114 Memcache _cache; 115 116 117 Nullable!V get_inter(V)(string key) 118 { 119 string data = _cache.get(key); 120 return DeserializeToObject!V(cast(byte[])data); 121 } 122 123 void put_inter(V)(string key , V v , uint expired) 124 { 125 _cache.set(key , cast(string)SerializeToByte(v) , cast(int)expired); 126 } 127 128 bool remove_inter(string key) 129 { 130 return _cache.del(key); 131 } 132 133 134 }